package scuts.core;

import scuts.core.FlatMap;
import scuts.core.types.ProgressiveFuture;
import utest.Assert;
using scuts.core.FlatMap;
import scuts.core.types.Option;

class FlatMapTest 
{
  public function new() 
  {
      
  }
  
  public function testFuture() 
  {
    var f1 = new ProgressiveFuture();
    var f2 = new ProgressiveFuture();
    var f3 = new ProgressiveFuture();
    var i1 = -1;
    var i2 = -1;
    var result = -1;
    var last = f1
               .flatMap(function (i) { i1 = i; return f2;})
               .flatMap(function (i) {i2 = i; return f3;});
    

    last.deliverTo(function (r) result = r);
    
    Assert.equals(-1, i1);    
    f1.deliver(1);
    Assert.equals(1, i1);
    
    Assert.equals(-1, i2);
    f2.deliver(2);
    Assert.equals(2,i2);
    
    Assert.equals(-1, result);
    
    
    f3.deliver(2);
    Assert.equals(2, result);
    
    
  }
  
  public function testIterator() 
  {
    var iter = [1, 2].iterator();
    var func = function (i) return ["a", "b"].iterator();
    
    var res = iter.flatMap(func);
    
    Assert.isTrue(res.hasNext());
    Assert.same("a", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("b", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("a", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("b", res.next());
    Assert.isFalse(res.hasNext());
        
    
  }
  
  public function testIteratorOption() 
  {
    var iter = [Some(1), Some(2), None].iterator();
    var func = function (i) return [Some(1)].iterator();
    
    var res = iter.flatMap(func);
    
    Assert.isTrue(res.hasNext());
    Assert.same(Some(1), res.next());
    Assert.isTrue(res.hasNext());
    Assert.same(Some(1), res.next());
    Assert.isFalse(res.hasNext());
    
  }
  
  public function testLazyIterator() 
  {
    var iter = function () return [1, 2].iterator();
    var func = function (i) return function () return ["a", "b"].iterator();
    
    var lazy = iter.flatMap(func);
    var res = lazy();
    
    Assert.isTrue(res.hasNext());
    Assert.same("a", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("b", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("a", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("b", res.next());
    Assert.isFalse(res.hasNext());
    
    var res = lazy();
    
    Assert.isTrue(res.hasNext());
    Assert.same("a", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("b", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("a", res.next());
    Assert.isTrue(res.hasNext());
    Assert.same("b", res.next());
    Assert.isFalse(res.hasNext());
        
    
  }
  
}